package com.sfl.api_backend.controller.download;

import com.sfl.api_backend.entity.Labels;
import com.sfl.api_backend.mapper.LabelsMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.*;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.web.bind.annotation.*;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.Future;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
 * @Author szc
 * @create 2023/2/6 11:14
 */
@RestController
@RequestMapping("/download")
@Slf4j
public class testDownload {
    @javax.annotation.Resource
    private LabelsMapper labelsMapper;

    @RequestMapping("/test")
    public ResponseEntity<InputStreamResource> downloadFile()
            throws IOException {

        //读取文件
        String filePath = "E:/tmp/test.nii.gz";

        log.info(String.format("downloadFile", filePath));

        FileSystemResource file = new FileSystemResource(filePath);
        //设置响应头
        HttpHeaders headers = new HttpHeaders();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Content-Disposition", String.format("attachment; filename=\"%s\"", file.getFilename()));
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");

        return ResponseEntity
                .ok()
                .headers(headers)
                .contentLength(file.contentLength())
                .contentType(MediaType.parseMediaType("application/octet-stream"))
                .body(new InputStreamResource(file.getInputStream()));
    }

    @GetMapping("/nii")
    public ResponseEntity<Resource> getNiiFile(@RequestParam("labelId") String labelId, @RequestParam("filename") String filename) throws IOException {
        // 获取 nii 文件的输入流
        try{
            System.out.println(filename);
            Labels labels = labelsMapper.selectById(labelId);

            String filePath = labels.getTheerDobjPath()+"\\"+filename;
            Resource niiResource = new FileSystemResource(filePath);
            InputStream inputStream = niiResource.getInputStream();

            // 构建 HTTP 响应
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setContentDisposition(ContentDisposition.attachment().filename(filePath).build());
            return new ResponseEntity<>(new InputStreamResource(inputStream), headers, HttpStatus.OK);
        }
        catch (Exception e){
            System.out.println(e);
            HttpHeaders headers = new HttpHeaders();
            return new ResponseEntity<>(headers,HttpStatus.BAD_GATEWAY);
        }
    }

    @GetMapping("/nii2")
    public ResponseEntity<Resource> getNiiFile2(@RequestParam("labelId") String labelId){
        // 获取 nii 文件的输入流
        try {
            System.out.println(labelId);
            Labels labels = labelsMapper.selectById(labelId);

            Path folderPath = Paths.get(labels.getTheerDobjPath());
            long fileCount = countFiles(folderPath);

            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream);

            for (int i = 1;i <= fileCount; i++) {
                String filename = "Label"+i+".obj";
                String filePath = labels.getTheerDobjPath() + "/" +filename;
                System.out.println(filePath);
                Resource fileResource = new FileSystemResource(filePath);

                zipOutputStream.putNextEntry(new ZipEntry(fileResource.getFilename()));
                InputStream inputStream = fileResource.getInputStream();
                byte[] buffer = new byte[1024];
                int length;
                while ((length = inputStream.read(buffer)) > 0) {
                    zipOutputStream.write(buffer, 0, length);
                }
                zipOutputStream.closeEntry();
            }
            zipOutputStream.close();

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setContentDisposition(ContentDisposition.attachment().filename("files.zip").build());

            return new ResponseEntity<>(new ByteArrayResource(byteArrayOutputStream.toByteArray()), headers, HttpStatus.OK);
        } catch (Exception e) {
            System.out.println(e);
            HttpHeaders headers = new HttpHeaders();
            return new ResponseEntity<>(headers, HttpStatus.BAD_GATEWAY);
        }
    }

    public static long countFiles(Path folderPath) throws IOException {
        try (Stream<Path> files = Files.list(folderPath)) {
            return files.filter(Files::isRegularFile).count();
        }
    }

    @GetMapping("/mesh")
    public ResponseEntity<Resource> getMesh(@RequestParam("filename") String filename) throws IOException {
        try{
            String filePath = "D:\\Sfl\\files\\597561\\labels\\253804\\"+filename;
            Resource niiResource = new FileSystemResource(filePath);
            InputStream inputStream = niiResource.getInputStream();

            // 构建 HTTP 响应
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setContentDisposition(ContentDisposition.attachment().filename(filePath).build());
            return new ResponseEntity<>(new InputStreamResource(inputStream), headers, HttpStatus.OK);
        }
        catch (Exception e){
            System.out.println(e);
            HttpHeaders headers = new HttpHeaders();
            return new ResponseEntity<>(headers,HttpStatus.BAD_GATEWAY);
        }
    }

    @GetMapping("/dcm/{filename:.+}")
    public ResponseEntity<Resource> getDicomFile(@PathVariable String filename) {
        try {
            System.out.println(filename);
            Resource niiResource = new FileSystemResource("D:\\Sfl\\files\\597561\\labels\\253804\\dcm\\" + filename);
            InputStream inputStream = niiResource.getInputStream();

            // 构建 HTTP 响应
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setContentDisposition(ContentDisposition.attachment().filename("D:\\Sfl\\files\\597561\\labels\\253804\\dcm\\" + filename).build());
            return new ResponseEntity<>(new InputStreamResource(inputStream), headers, HttpStatus.OK);
        } catch (Exception e) {
            return ResponseEntity.status(500).build();
        }
    }

    @Async
    Future<InputStream> getDcm(String labelId) throws FileNotFoundException {

        String SeriesPath = "D:\\Sfl\\files\\597561\\labels\\253804\\dcm\\" + labelId;

        return AsyncResult.forValue(new FileInputStream(SeriesPath));

    }
}
